昨天我們建立 IAM Group 與 policy,並說明 policy 管理原則。
create_login_profile = false
的選項
如果你是管理員,在更改 admin 帳號的權限與登入設定時,一定要多加注意
本日進度
賽後文章會整理放到個人的部落格上 http://chechia.net/
Gruntwork Guide 在完成 group 與 policy 設定後,下一個需要做的是加強 user 登入的安全性
需要做的事情有
Multi-factor authentication 是常用的認證方式
然而 如 Gruntwork Guide 在 MFA Policy所述,要 enforce MFA 到所有的 AWS API 會有諸多困難
Gruntwork Guide 中建議在以下情境中啟用 MFA 就好
Password Policy 指的是對於 user 自己設定的密碼要符合一定的規範
由於我們使用的 external module terraform-aws-iam 已經整合了 password policy,所以我們這邊直接在 input 中開啟即可以使用
pgp (Pretty Good Privacy) 是非常常用的非對稱加密工具
為何 iam user 創建會牽扯到 pgp?
admin 以 gpg(GnuPG) 為例非對稱加密 (local exposure)
上面的做法 terraform state 與 admin local 會看到明碼 password,不夠安全。
aws 提供一個改進的做法,terraform state 只存 encrypted text
pre-requisite
安裝 gpg
sudo port install gpg
gpg --version
gpg --full-generate-key
列出自己有的 secret key (private key)
gpg --list-secret-keys --keyid-format=long
export public key
gpg --armor --export 3AA5C34371567BD2
-----BEGIN PGP PUBLIC KEY BLOCK-----
mQINBF9oN7ABEADeJ5BO3RsvfB0RpU3ZtI3AZmLmMfoaQ41QtkLoFEhF0XnSBNhH
....
ARFfAR39B4hHAnA+/+scVFdGT8i9kuYxk8Ocb7zHgULrOBfKEPEQ5XLmdiqAD+DN
jO2IFPM=
-----END PGP PUBLIC KEY BLOCK-----
NOTE: private key 是鑰匙,public key 是鎖頭,永遠不要把 private key 傳出去,而是把 public key 傳出去讓別人加密,用 public key 加密過的東西,只能用手上這把 private key 解開,也就是專屬你的
在 keybase.io 上面註冊後,上傳你的 pgp public key
NOTE: 如果不啟用 pgp-key,admin terraform apply 新 user 後拿到的 password 就會是明碼,可以透過 gpg 工具加密,在透過網路傳給對方
這邊我們先使用 Accounting 先做測試,啟用 login profile
NOTE: 你知道自己是 admin,就請不要拿自己的 User 做測試,壞了很麻煩
將 terragrunt.hcl 改成
Accounting = {
groups = ["billing"]
pgp_key = "keybase:chechiachang"
create_login_profile = true
create_access_keys = false # accounting always use web console, won't use access key
}
}
接著要改 module 中的 code,將 module 的 output 接出來到上層的 root module
output.tf
# https://github.com/terraform-aws-modules/terraform-aws-iam/blob/master/modules/iam-user/outputs.tf
output "keybase_password_pgp_message" {
description = "Encrypted password"
value = {
for key, value in module.iam_user : key => value.keybase_password_pgp_message
}
}
output "keybase_password_decrypt_command" {
description = "Decrypt user password command"
value = {
for key, value in module.iam_user : key => value.keybase_password_decrypt_command
}
}
然後我們試著 plan
aws-vault exec terraform-30day-root-iam-user --no-session -- terragrunt plan
Terraform will perform the following actions:
# module.iam_user["Accounting"].aws_iam_user_login_profile.this[0] will be created
+ resource "aws_iam_user_login_profile" "this" {
+ encrypted_password = (known after apply)
+ id = (known after apply)
+ key_fingerprint = (known after apply)
+ password = (known after apply)
+ password_length = 20
+ password_reset_required = false
+ pgp_key = "keybase:chechiachang"
+ user = "Accounting"
}
Plan: 1 to add, 0 to change, 0 to destroy.
Changes to Outputs:
+ keybase_password_decrypt_command = {
+ Accounting = (known after apply)
+ Administrator = null
}
+ keybase_password_pgp_message = {
+ Accounting = (known after apply)
+ Administrator = null
}
符合預期!
keybase_password_pgp_message
的 Accounting = (known after apply)
應該是加密過的 output那直接來 apply 試試看
aws-vault exec terraform-30day-root-iam-user --no-session -- terragrunt apply
Outputs:
keybase_password_decrypt_command = {
"Accounting" = <<-EOT
echo "wcFMA4U4ylYlNYTfAQ/+KLtNeJqOqK/V3pNdcRh9nvyDw/huJfaYF7Ab/YdKqLKNVySBqc6HY8xedmER5Wn78RlG962/f772u8UlQN4XCOjOLjyOaNL8K0tkeoSVg+XXPx2qJO9Myc1d+74rG57biUD26XpwfS7+ryIjaHf+NzjisExZy2mgiMIzzAlfqTzRAc+jYP11wZcyFGwOe9pMq6BJy7FH5935ndVgNLCgYtSjgIV5b5kWQ3SDr0E9egAHnoAcHs8mni71x7OL7OCc/bS3nJSLz1jRkMoukWyQQ3+lM7Nwi36NSJneIKxW5f7lSxr7Bx+W3mx6gZgb18yRVIwbVW5iDFsAQOFb0zOHUf8tm3tAQ0F79Yeqy9sfLCfUUjVpCENEJe5FtwJkI8EbHKe8mGnYA4dbHaCkIDgVa8TZ4mdXl7yVZx0adlkKFIS48niwPHxMErZYqnRBitUCGdaH0bHcpPcnSVolLljZmXZUrntMjIEb9FGYbgl6hOiRF9MR3RQL5DNmpS7uSqU7V6TyhVbAOJO2oR01Z7hXdAMxZ54O+h06jN7fzvLrUSMWvUz/wp+JJnIDYNwu75Dvicn6NmXrP3fH3M8xmYIEPhpSvOldNzB4DMqQdD6tN+DphFFyvFwuLnWKWKOY+pbNXkd5q0H3A69owxgsONoOL1JqjZgOdcLtWTq+g9XqU5XSRQGo1ei5Ctv2f5yAHZuI2smwJkTA88SuyZqJNwRixw5OPpUDOuWxhK6xftsN7M1/TnioX8Ch3RTow7H0dvMFFD3ocvjG4A==" | base64 --decode | keybase pgp decrypt
EOT
"Administrator" = tostring(null)
}
keybase_password_pgp_message = {
"Accounting" = <<-EOT
-----BEGIN PGP MESSAGE-----
Version: Keybase OpenPGP v2.0.76
Comment: https://keybase.io/crypto
wcFMA4U4ylYlNYTfAQ/+KLtNeJqOqK/V3pNdcRh9nvyDw/huJfaYF7Ab/YdKqLKNVySBqc6HY8xedmER5Wn78RlG962/f772u8UlQN4XCOjOLjyOaNL8K0tkeoSVg+XXPx2qJO9Myc1d+74rG57biUD26XpwfS7+ryIjaHf+NzjisExZy2mgiMIzzAlfqTzRAc+jYP11wZcyFGwOe9pMq6BJy7FH5935ndVgNLCgYtSjgIV5b5kWQ3SDr0E9egAHnoAcHs8mni71x7OL7OCc/bS3nJSLz1jRkMoukWyQQ3+lM7Nwi36NSJneIKxW5f7lSxr7Bx+W3mx6gZgb18yRVIwbVW5iDFsAQOFb0zOHUf8tm3tAQ0F79Yeqy9sfLCfUUjVpCENEJe5FtwJkI8EbHKe8mGnYA4dbHaCkIDgVa8TZ4mdXl7yVZx0adlkKFIS48niwPHxMErZYqnRBitUCGdaH0bHcpPcnSVolLljZmXZUrntMjIEb9FGYbgl6hOiRF9MR3RQL5DNmpS7uSqU7V6TyhVbAOJO2oR01Z7hXdAMxZ54O+h06jN7fzvLrUSMWvUz/wp+JJnIDYNwu75Dvicn6NmXrP3fH3M8xmYIEPhpSvOldNzB4DMqQdD6tN+DphFFyvFwuLnWKWKOY+pbNXkd5q0H3A69owxgsONoOL1JqjZgOdcLtWTq+g9XqU5XSRQGo1ei5Ctv2f5yAHZuI2smwJkTA88SuyZqJNwRixw5OPpUDOuWxhK6xftsN7M1/TnioX8Ch3RTow7H0dvMFFD3ocvjG4A==
-----END PGP MESSAGE-----
EOT
"Administrator" = tostring(null)
}
上面的 PGP message 是加密過的 text,可以放心的傳遞
但我是使用 gpg 而不是 keybase,也是可以解開
echo "wcFMA4U4ylYlNYTfAQ/+KLtNeJqOqK/V3pNdcRh9nvyDw/huJfaYF7Ab/YdKqLKNVySBqc6HY8xedmER5Wn78RlG962/f772u8UlQN4XCOjOLjyOaNL8K0tkeoSVg+XXPx2qJO9Myc1d+74rG57biUD26XpwfS7+ryIjaHf+NzjisExZy2mgiMIzzAlfqTzRAc+jYP11wZcyFGwOe9pMq6BJy7FH5935ndVgNLCgYtSjgIV5b5kWQ3SDr0E9egAHnoAcHs8mni71x7OL7OCc/bS3nJSLz1jRkMoukWyQQ3+lM7Nwi36NSJneIKxW5f7lSxr7Bx+W3mx6gZgb18yRVIwbVW5iDFsAQOFb0zOHUf8tm3tAQ0F79Yeqy9sfLCfUUjVpCENEJe5FtwJkI8EbHKe8mGnYA4dbHaCkIDgVa8TZ4mdXl7yVZx0adlkKFIS48niwPHxMErZYqnRBitUCGdaH0bHcpPcnSVolLljZmXZUrntMjIEb9FGYbgl6hOiRF9MR3RQL5DNmpS7uSqU7V6TyhVbAOJO2oR01Z7hXdAMxZ54O+h06jN7fzvLrUSMWvUz/wp+JJnIDYNwu75Dvicn6NmXrP3fH3M8xmYIEPhpSvOldNzB4DMqQdD6tN+DphFFyvFwuLnWKWKOY+pbNXkd5q0H3A69owxgsONoOL1JqjZgOdcLtWTq+g9XqU5XSRQGo1ei5Ctv2f5yAHZuI2smwJkTA88SuyZqJNwRixw5OPpUDOuWxhK6xftsN7M1/TnioX8Ch3RTow7H0dvMFFD3ocvjG4A==" | base64 --decode | gpg --decrypt
就取得 Accounting 的初次登入密碼的,趕快到 aws console 上面試試看
NOTE: 想要在 browser 同時多開 aws login session 的話,可以參考 chrome plugin session box
登入 aws web console
%
不是密碼的一部分,是 EOL (End of line) indicator,記得去掉順利登入拉
Accounting 的權限是不能動用 EC2 API 的,切到 EC2 頁面直接 API Error,也符合預期
上面的變更我們的 PR 如下
明天還有 Administrator 帳戶需要處理,會再更麻煩一些